package org.tbjd.client.guis.taskList;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.tbjd.client.beans.Task;
import org.tbjd.client.constants.NotificationsConstants;
import org.tbjd.client.customWidgets.TreeGrid;
import org.tbjd.client.exceptions.NoUpperDecisionmakerFoundException;
import org.tbjd.client.exceptions.NoUpperMediatorFoundException;
import org.tbjd.client.exceptions.TBJDException;
import org.tbjd.client.interfaces.Builder;
import org.tbjd.client.interfaces.Decisionmaker;
import org.tbjd.client.interfaces.Displayer;
import org.tbjd.client.interfaces.HasDragController;
import org.tbjd.client.interfaces.HasMediator;
import org.tbjd.client.interfaces.Observer;
import org.tbjd.client.mediators.AbstractMediator;
import org.tbjd.client.widgetProviders.TasksListWidgetProvider;

import com.allen_sauer.gwt.dnd.client.DragController;
import com.google.gwt.user.client.ui.Button;
import com.google.gwt.user.client.ui.ClickListener;
import com.google.gwt.user.client.ui.Composite;
import com.google.gwt.user.client.ui.HorizontalPanel;
import com.google.gwt.user.client.ui.Label;
import com.google.gwt.user.client.ui.VerticalPanel;
import com.google.gwt.user.client.ui.Widget;

public class TaskListGui extends Composite implements Builder, Observer, Displayer, HasMediator, Decisionmaker, HasDragController {

	static private TaskListGui instance = null;
	private VerticalPanel container = null;
	private HorizontalPanel taskListMenu = null;

	private TreeGrid treeGrid = null;

	private AbstractMediator mediator = null;
	private Button addButton;
	private Button deleteButton;
	private Button switchTaskTypeButton;

	private TaskListGui() {
		build();
		initWidget(this.container);
	}

	public void build() {

		buildTaskListMenuPanel();

		buildTaskListPanel();

		this.container.add(taskListMenu);
		this.container.add(treeGrid);
	}

	static public TaskListGui getInstance() {
		if (instance == null) {
			instance = new TaskListGui();
		}
		return instance;
	}

	public void display() {
		System.out.println("TaskListGui.display() ");
	}

	public void setMediator(AbstractMediator mediator) {
		this.mediator = mediator;
		this.mediator.addObserver(this);
	}

	public void setDragController(DragController dragController) {
	}

	public void decide(Object action) {
		System.out.println("TaskListGui.decide()");
		
		if (((Map<?, ?>) action).containsKey(NotificationsConstants.TREEGRIDITEM_SELECTED)) {
			// get the selected item
			
			// TODO if subtask => don't do anything
//			if (treeGrid.getSelectedItem() == null){
//				deleteButton.setEnabled(false);
//				switchTaskTypeButton.setEnabled(false);
//			}else{
//				deleteButton.setEnabled(true);
//				switchTaskTypeButton.setEnabled(true);
//				
//			}
		
		} else {

			try {
				delegate(action);
			} catch (NoUpperDecisionmakerFoundException e) {
				e.printStackTrace();
			} catch (NoUpperMediatorFoundException e) {
				e.printStackTrace();
			}
		}
	}

	public void delegate(Object action) throws NoUpperDecisionmakerFoundException, NoUpperMediatorFoundException {
		System.out.println("TaskListGui.delegate()");
		try {
			this.mediator.decide(action);
		} catch (TBJDException e) {
			e.printStackTrace();
		}
	}

	public void handle(Object action) {
	}

	public void update(Object sender) {
		System.out.println("TaskListGui.update()");
		if (((Map<?, ?>) sender).containsKey(NotificationsConstants.TASKS)) {
			// this.treeGrid.setTreeGridItems((List<TreeGridItem>) ((Map<?, ?>) sender).get(NotificationsConstants.DECORATED_TASKS));
			this.treeGrid.display((ArrayList<Task>) ((Map<?, ?>) sender).get(NotificationsConstants.TASKS));
		}

		if (((Map<?, ?>) sender).containsKey(NotificationsConstants.TASKMANAGER_RESULT)) {
			System.out.println("TaskListGui.update() - TASKMANAGER_RESULT");

			List<Task> lstUpdatedTasks = (List<Task>) ((Map<?, ?>) sender).get(NotificationsConstants.TASKMANAGER_RESULT);

			// //TODO the bean in the treegrid. If exist then update else addInput(newTask). Display items
			this.treeGrid.display((ArrayList<Task>) lstUpdatedTasks);

		}

		if (((Map<?, ?>) sender).containsKey(NotificationsConstants.TASKMANAGER_RESULT_rowsToRemove)) {
			this.treeGrid.resetSelectedItem();
			this.treeGrid.deleteRows((Integer) ((Map<?, ?>) sender).get(NotificationsConstants.TASKMANAGER_RESULT_rowsToRemove));
		}
	}

	private ArrayList<Widget> getColumnHeader() {
		ArrayList<Widget> columnHeader = new ArrayList<Widget>();

		columnHeader.add(new Label(""));
		columnHeader.add(new Label("Task"));
		columnHeader.add(new Label("Duration"));
		columnHeader.add(new Label("Progress"));
		columnHeader.add(new Label("Begin"));
		columnHeader.add(new Label("End"));
		return columnHeader;
	}

	private void buildTaskListMenuPanel() {
		this.taskListMenu = new HorizontalPanel();
		this.taskListMenu.setStyleName("tbjd-taskListMenu");

		addButton = new Button("add");
		deleteButton = new Button("del");
		switchTaskTypeButton = new Button("T<->P");
		
		this.taskListMenu.add(addButton);
		this.taskListMenu.add(deleteButton);
		this.taskListMenu.add(switchTaskTypeButton);

		addButton.addClickListener(new ClickListener() {

			public void onClick(Widget sender) {
				Map<Integer, Object> map = new HashMap<Integer, Object>();

				map.put(NotificationsConstants.TASK_ADDED, treeGrid.getSelectedItem());
				if (treeGrid.getSelectedItem() == null) {
					map.put(NotificationsConstants.TASK_LEVEL, treeGrid.getLastLevel() - 1);

				} else {
					map.put(NotificationsConstants.TASK_LEVEL, treeGrid.getSelectedItem().getLevel());

				}

				try {
					delegate(map);
				} catch (NoUpperDecisionmakerFoundException e) {
					e.printStackTrace();
				} catch (NoUpperMediatorFoundException e) {
					e.printStackTrace();
				}
			}

		});

		deleteButton.addClickListener(new ClickListener() {

			public void onClick(Widget sender) {
				Map<Integer, Object> map = new HashMap<Integer, Object>();

				if (treeGrid.getSelectedItem() != null) {
					map.put(NotificationsConstants.TASK_DELETED, treeGrid.getSelectedItem());
					map.put(NotificationsConstants.TASK_LEVEL, treeGrid.getSelectedItem().getLevel());

					try {
						delegate(map);
					} catch (NoUpperDecisionmakerFoundException e) {
						e.printStackTrace();
					} catch (NoUpperMediatorFoundException e) {
						e.printStackTrace();
					}
				}

			}

		});

		switchTaskTypeButton.addClickListener(new ClickListener() {

			public void onClick(Widget sender) {

				if (treeGrid.getSelectedItem() != null) {

					Map<Integer, Object> map = new HashMap<Integer, Object>();
					map.put(NotificationsConstants.TASK_TYPE_SWITCHED, treeGrid.getSelectedItem());

					try {
						delegate(map);
					} catch (NoUpperDecisionmakerFoundException e) {
						e.printStackTrace();
					} catch (NoUpperMediatorFoundException e) {
						e.printStackTrace();
					}
				}
			}

		});
	}

	private void buildTaskListPanel() {
		this.container = new VerticalPanel();
		this.container.setStyleName("tbjd-taskList");

		treeGrid = new TreeGrid(getColumnHeader());
		String[] columnsWidth = { "10px", "200px", "50px", "50px", "50px", "50px" };

		try {
			treeGrid.setColumnsWidth(columnsWidth);
		} catch (Exception e) {
			e.printStackTrace();
		}

		treeGrid.setItemWidgetProvider(new TasksListWidgetProvider());
	}

	public void display(List<?> updatedBeans) {
		// TODO Auto-generated method stub

	}

	public Widget getBuildedWidget() {
		return this.container;
	}
}
